package com.ruoyi.locksApi.service.serviceImpl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.lock.domain.*;
import com.ruoyi.lock.mapper.ABuildHomeMapper;
import com.ruoyi.lock.mapper.ADeviceMapper;
import com.ruoyi.lock.mapper.AOpenlockMapper;
import com.ruoyi.lock.mapper.ATenantkeyMapper;
import com.ruoyi.lock.mapper.ATenantuserMapper;
import org.apache.commons.lang3.StringUtils;
import com.ruoyi.lock.service.IACheckaInService;
import com.ruoyi.lock.service.IALogsService;
import com.ruoyi.lock.service.IATenantkeyService;
import com.ruoyi.locksApi.domain.*;
import com.ruoyi.locksApi.mapper.ATaskMapper;
import com.ruoyi.locksApi.service.IATaskService;
import com.ruoyi.locksApi.service.LockApiService;
import com.ruoyi.locksApi.service.impl.ApartmentTokenTask;
import com.ruoyi.lock.config.LockApiConfig;
import com.ruoyi.tengxun.service.ISmsService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;
import java.security.MessageDigest;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import com.ruoyi.lock.domain.ABuildHome;

@Slf4j
@Service
public class LockApiServiceImpl implements LockApiService {

    @Autowired
    private ATenantkeyMapper aTenantkeyMapper;
    @Autowired
    private AOpenlockMapper aOpenlockMapper;
    @Autowired
    private ABuildHomeMapper aBuildHomeMapper;
    @Autowired
    private ATenantuserMapper aTenantuserMapper;
    @Autowired
    private RedisCache redisCache;
    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private LockApiConfig lockApiConfig;
    @Autowired
    private ApartmentTokenTask apartmentTokenTask;

    /**
     * 处理开门记录上报
     *
     * @param  开门记录数据
     * @return 处理结果
     */
    @Override
    public int processOpenLog(String roomId ,String type ,String logId,String lockKeyId,String remark) {
        Long tenantId = 0L;
        Long userId = 0L;
        ATenantkey tenantkey = null;
        ABuildHome roomInfo = aBuildHomeMapper.selectABuildHomeByRoomNum(roomId);
        if (roomInfo == null){
            log.info("找不到房间: {}", roomId);
            return -1; // 找不到房间返回-1，表示处理失败
        }
        Long homeId = roomInfo.getId();

        if (lockKeyId != null && !lockKeyId.isEmpty()) {
            tenantkey = aTenantkeyMapper.selectATenantkeyByMacAndKeyId(lockKeyId,roomInfo.getId());
            if (tenantkey != null) {
                tenantId = tenantkey.getTenantId();
                userId = tenantkey.getTenantId();
            }
        }
        
        // 根据是否有用户ID来决定remark格式
        String finalRemark = remark;
        if (userId != null && userId > 0) {
            // 有用户ID时，查询用户信息并格式化remark
            try {
                ATenantuser tenantUser = aTenantuserMapper.selectATenantuserById(userId);
                if (tenantUser != null && StringUtils.isNotEmpty(tenantUser.getName())) {
                    // 根据开门类型设置不同的remark格式
                    if ("2".equals(type)) {
                        finalRemark = "「" + tenantUser.getName() + "」用「密码」开锁";
                    } else if ("4".equals(type)) {
                        finalRemark = "「" + tenantUser.getName() + "」用「卡」开锁";
                    } else {
                        finalRemark = "「" + tenantUser.getName() + "」用「远程」开锁";
                    }
                }
            } catch (Exception e) {
                log.warn("查询用户信息失败，使用原始remark: {}", e.getMessage());
                finalRemark = remark;
            }
        }
        // 没有用户ID时，保持原来的remark格式
        
        // 后续赋值
        AOpenlock aOpenlock = new AOpenlock();
        aOpenlock.setUserId(userId);
        aOpenlock.setTenantId(tenantId);
        aOpenlock.setHomeId(homeId);
        aOpenlock.setRemark(finalRemark);
        aOpenlock.setCreateTime(DateUtils.getNowDate());
        // 根据钥匙类型设置开门方式
        if ("2".equals(type)) {
            aOpenlock.setType("1"); // 密码开门
        } else if ("4".equals(type)) {
            aOpenlock.setType("2"); // 卡片开门
        }else  {
            aOpenlock.setType("3"); // 远程开门
        }
        // 保存开门记录
        int result = aOpenlockMapper.insertAOpenlock(aOpenlock);
        log.info("开门记录保存结果: {}", result > 0 ? "成功" : "失败");
        log.info("开门记录: userId={}, tenantId={}, homeId={}, remark={}", userId, tenantId, homeId, finalRemark);
        return result;
    }



    @Override
    public JSONObject apartmentAddCardKey(String roomId, String phoneNo, String keyName, Long beginTime, Long endTime, String cardNum,String keyGroupld,String idCardNumber) {
        // 获取token
        String tokenId = redisCache.getCacheObject("apartment:token");
        if (tokenId == null) {
            apartmentTokenTask.refreshToken();
            tokenId = redisCache.getCacheObject("apartment:token");
            if (tokenId == null) {
                JSONObject error = new JSONObject();
                error.put("resultCode", 500005);
                error.put("reason", "tokenId不存在或已过期，自动登录失败");
                return error;
            }
        }
        try {
            // 1. 卡号补齐10位并AES加密
            String cardNumEnc = AESUtil.encryptKey(tokenId, cardNum);
            // 2. 组装data
            Map<String, Object> data = new HashMap<>();
            data.put("roomId", roomId);
            if(keyGroupld !=null){
                data.put("keyGroupId", Integer.valueOf(keyGroupld));
//                data.put("email", idCardNumber+"@qq.com");

            }else{
                data.put("email", idCardNumber+"@hflz.com");
            }
            data.put("keyName", keyName);
//            data.put("phoneNo", phoneNo);

            data.put("beginTime", beginTime);
            data.put("endTime", endTime);
            System.err.println(beginTime);
            System.err.println(endTime);
            data.put("cardNum", cardNumEnc);
            // 3. 组装请求体
            Map<String, Object> req = new HashMap<>();
            req.put("method", "apartmentAddCardKey");
            req.put("tokenId", tokenId);
            req.put("data", data);
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.valueOf("text/json;charset=utf-8"));
            headers.add("Content-Version", "1.2");
            HttpEntity<String> entity = new HttpEntity<>(com.alibaba.fastjson.JSONObject.toJSONString(req), headers);
            String respStr = restTemplate.postForObject(lockApiConfig.getLoginUrl(), entity, String.class);
            JSONObject resp = com.alibaba.fastjson.JSONObject.parseObject(respStr);
            // token失效自动重试
            if (resp != null && (resp.getIntValue("resultCode") == 500005 || resp.getIntValue("resultCode") == 304)) {
                apartmentTokenTask.refreshToken();
                tokenId = redisCache.getCacheObject("apartment:token");
                req.put("tokenId", tokenId);
                entity = new HttpEntity<>(com.alibaba.fastjson.JSONObject.toJSONString(req), headers);
                respStr = restTemplate.postForObject(lockApiConfig.getLoginUrl(), entity, String.class);
                resp = com.alibaba.fastjson.JSONObject.parseObject(respStr);
            }
            return resp;
        } catch (Exception e) {
            JSONObject error = new JSONObject();
            error.put("resultCode", 500006);
            error.put("reason", "加密或请求异常: " + e.getMessage());
            return error;
        }
    }


    @Override
    public JSONObject apartmentAddPwdKey(String roomId, String phoneNo, String keyName, Long beginTime, Long endTime, String cardNum,String keyGroupld,String idCardNumber) {
        // 获取token
        String tokenId = redisCache.getCacheObject("apartment:token");
        if (tokenId == null) {
            apartmentTokenTask.refreshToken();
            tokenId = redisCache.getCacheObject("apartment:token");
            if (tokenId == null) {
                JSONObject error = new JSONObject();
                error.put("resultCode", 500005);
                error.put("reason", "tokenId不存在或已过期，自动登录失败");
                return error;
            }
        }
        try {
            // 1. 卡号补齐10位并AES加密
            String cardNumEnc = AESUtil.encryptKey(tokenId, cardNum);
            // 2. 组装data
            Map<String, Object> data = new HashMap<>();
            data.put("roomId", roomId);
            if(keyGroupld !=null){
                data.put("keyGroupId", Integer.valueOf(keyGroupld));
//                data.put("email", idCardNumber+"@qq.com");

            }else{
                data.put("email", idCardNumber+"@hflz.com");
            }
            data.put("keyName", keyName);
//            data.put("phoneNo", phoneNo);

            data.put("beginTime", beginTime);
            data.put("endTime", endTime);
            System.err.println(beginTime);
            System.err.println(endTime);
            data.put("password", cardNumEnc);
            // 3. 组装请求体
            Map<String, Object> req = new HashMap<>();
            req.put("method", "apartmentAddPasswordKey");
            req.put("tokenId", tokenId);
            req.put("data", data);
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.valueOf("text/json;charset=utf-8"));
            headers.add("Content-Version", "1.2");
            HttpEntity<String> entity = new HttpEntity<>(com.alibaba.fastjson.JSONObject.toJSONString(req), headers);
            String respStr = restTemplate.postForObject(lockApiConfig.getLoginUrl(), entity, String.class);
            JSONObject resp = com.alibaba.fastjson.JSONObject.parseObject(respStr);
            // token失效自动重试
            if (resp != null && (resp.getIntValue("resultCode") == 500005 || resp.getIntValue("resultCode") == 304)) {
                apartmentTokenTask.refreshToken();
                tokenId = redisCache.getCacheObject("apartment:token");
                req.put("tokenId", tokenId);
                entity = new HttpEntity<>(com.alibaba.fastjson.JSONObject.toJSONString(req), headers);
                respStr = restTemplate.postForObject(lockApiConfig.getLoginUrl(), entity, String.class);
                resp = com.alibaba.fastjson.JSONObject.parseObject(respStr);
            }
            return resp;
        } catch (Exception e) {
            JSONObject error = new JSONObject();
            error.put("resultCode", 500006);
            error.put("reason", "加密或请求异常: " + e.getMessage());
            return error;
        }
    }

    /**
     * 删除钥匙接口
     * @param keyId 授权ID
     * @return 响应JSON
     */
    public JSONObject apartmentDelKey(String keyId) {
        String tokenId = redisCache.getCacheObject("apartment:token");
        if (tokenId == null) {
            apartmentTokenTask.refreshToken();
            tokenId = redisCache.getCacheObject("apartment:token");
            if (tokenId == null) {
                JSONObject error = new JSONObject();
                error.put("resultCode", 500005);
                error.put("reason", "tokenId不存在或已过期，自动登录失败");
                return error;
            }
        }
        try {
            Map<String, Object> data = new HashMap<>();
            data.put("keyId", keyId);
            Map<String, Object> req = new HashMap<>();
            req.put("method", "apartmentDelKey");
            req.put("tokenId", tokenId);
            req.put("data", data);
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.valueOf("text/json;charset=utf-8"));
            headers.add("Content-Version", "1.0");
            HttpEntity<String> entity = new HttpEntity<>(com.alibaba.fastjson.JSONObject.toJSONString(req), headers);
            String respStr = restTemplate.postForObject(lockApiConfig.getLoginUrl(), entity, String.class);
            JSONObject resp = com.alibaba.fastjson.JSONObject.parseObject(respStr);
            // token失效自动重试
            if (resp != null && (resp.getIntValue("resultCode") == 500005 || resp.getIntValue("resultCode") == 304)) {
                apartmentTokenTask.refreshToken();
                tokenId = redisCache.getCacheObject("apartment:token");
                req.put("tokenId", tokenId);
                entity = new HttpEntity<>(com.alibaba.fastjson.JSONObject.toJSONString(req), headers);
                respStr = restTemplate.postForObject(lockApiConfig.getLoginUrl(), entity, String.class);
                resp = com.alibaba.fastjson.JSONObject.parseObject(respStr);
            }
            return resp;
        } catch (Exception e) {
            JSONObject error = new JSONObject();
            error.put("resultCode", 500006);
            error.put("reason", "请求异常: " + e.getMessage());
            return error;
        }
    }

    /**
     * 单个退房接口
     * @param roomId 房间ID
     * @param phoneNo 手机号
     * @return 响应JSON
     */
    @Override
    public JSONObject apartmentRoomSingleCheckOut(String roomId, String email) {
        String tokenId = redisCache.getCacheObject("apartment:token");
        if (tokenId == null) {
            apartmentTokenTask.refreshToken();
            tokenId = redisCache.getCacheObject("apartment:token");
            if (tokenId == null) {
                JSONObject error = new JSONObject();
                error.put("resultCode", 500005);
                error.put("reason", "tokenId不存在或已过期，自动登录失败");
                return error;
            }
        }
        try {
            // 组装data
            Map<String, Object> data = new HashMap<>();
            data.put("roomId", roomId);
            data.put("email", email);
            
            // 组装请求体
            Map<String, Object> req = new HashMap<>();
            req.put("method", "apartmentRoomSingleCheckOut");
            req.put("tokenId", tokenId);
            req.put("data", data);
            
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.valueOf("text/json;charset=utf-8"));
            headers.add("Content-Version", "1.3");
            HttpEntity<String> entity = new HttpEntity<>(com.alibaba.fastjson.JSONObject.toJSONString(req), headers);
            
            String respStr = restTemplate.postForObject(lockApiConfig.getLoginUrl(), entity, String.class);
            JSONObject resp = com.alibaba.fastjson.JSONObject.parseObject(respStr);
            
            // token失效自动重试
            if (resp != null && (resp.getIntValue("resultCode") == 500005 || resp.getIntValue("resultCode") == 304)) {
                apartmentTokenTask.refreshToken();
                tokenId = redisCache.getCacheObject("apartment:token");
                req.put("tokenId", tokenId);
                entity = new HttpEntity<>(com.alibaba.fastjson.JSONObject.toJSONString(req), headers);
                respStr = restTemplate.postForObject(lockApiConfig.getLoginUrl(), entity, String.class);
                resp = com.alibaba.fastjson.JSONObject.parseObject(respStr);
            }
            
            return resp;
        } catch (Exception e) {
            JSONObject error = new JSONObject();
            error.put("resultCode", 500006);
            error.put("reason", "退房请求异常: " + e.getMessage());
            return error;
        }
    }
}
